package com.example.demoweb.util.customFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.example.demoweb.dao.CustomFileRepository;
import com.example.demoweb.entity.CustomFile;
import com.example.demoweb.util.MD5Util;
import com.mongodb.gridfs.GridFSDBFile;
/**
 * 文件上传工具类
 * @author yanwin
 *
 */
@Component
@Transactional
public class CustomFileUtil {
	
	@Autowired
    public CustomFileRepository customFileRepository;
	
	@Autowired
	private GridFsTemplate gridFsTemplate;
	
	/**
	 * 上传文件
	 * @param file
	 * @return
	 */
	@Transactional(readOnly=false)
    public CustomFile saveFile(MultipartFile file,String bussinessId,String bussinessType) {
		CustomFile returnFile = null;
        try {
            CustomFile f = new CustomFile(file.getOriginalFilename(),  file.getContentType(), file.getSize(),file.getBytes());
            f.setMd5(MD5Util.getMD5(file.getInputStream()));
            /*f.setBussinessId(bussinessId);
            f.setBussinessType(bussinessType);*/
            returnFile = customFileRepository.save(f);
        } catch (IOException e) {
            throw new RuntimeException();
        }
        return returnFile;
    }
	
	/**
	 * 下载文件
	 * @param id
	 * @return
	 */
	public ResponseEntity<Object> download(String id) {
		CustomFile customFile = this.getFileById(id);
		if (customFile != null) {
			return ResponseEntity.ok()
					.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; fileName=\"" + customFile.getName() + "\"")
					.header(HttpHeaders.CONTENT_TYPE, "application/octet-stream")
					.header(HttpHeaders.CONTENT_LENGTH, customFile.getSize() + "").header("Connection", "close")
					.body(customFile.getContent());
		} else {
			return ResponseEntity.status(HttpStatus.NOT_FOUND).body("File was not fount");
		}
	}
	
	/**
	 * 预览图片
	 * @param id
	 * @return
	 */
	public ResponseEntity<Object> OnlineView(String id) {
        CustomFile customFile = this.getFileById(id);
        if (customFile != null) {
            return ResponseEntity
                    .ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "fileName=\"" + customFile.getName() + "\"")
                    .header(HttpHeaders.CONTENT_TYPE, customFile.getContentType() )
                    .header(HttpHeaders.CONTENT_LENGTH, customFile.getSize()+"")
                    .header("Connection",  "close") 
                    .body( customFile.getContent());
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("File was not fount");
        }

	}
	
	/**
	 * 根据id删除文件
	 * @param id
	 * @return
	 */
	public ResponseEntity<String> deleteFile(String id) {
		 try {
	        	this.removeFile(id);
	            return ResponseEntity.status(HttpStatus.OK).body("DELETE Success!");
	        } catch (Exception e) {
	        	e.printStackTrace();
	            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
	       }
	}
	
	/**
	 * 删除文件
	 * @param id
	 */
	@Transactional(readOnly=false)
    public void removeFile(String id) {
        customFileRepository.delete(id);
    }
	
	/**
	 * 根据id获取文件，返回CustomFile实体
	 * @param id
	 * @return CustomFile
	 */
    public CustomFile getFileById(String id) {
        return customFileRepository.findOne(id);
    }
    
    /**
     * 分页获取page
     * @param pageIndex
     * @param pageSize
     * @return
     */
    public List<CustomFile> listFilesByPage(int pageIndex, int pageSize) {
        Page<CustomFile> page = null;
        List<CustomFile> list = null;

        Sort sort = new Sort(Direction.DESC,"uploadDate"); 
        Pageable pageable = new PageRequest(pageIndex, pageSize, sort);

        page = customFileRepository.findAll(pageable);
        list = page.getContent();
        return list;
    }
    
    /**
     * 存储大于16m的文件
     * @param file
     */
    public ResponseEntity<String> storeFileInGridFs(MultipartFile file) {
    	try {
        	gridFsTemplate.store(file.getInputStream(), file.getOriginalFilename(), file.getContentType());
        	return ResponseEntity.status(HttpStatus.OK).body("upload Success!");
        } catch (Exception e) {
        	e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
       }
    }
    
    /**
     * 根据文件id下载大附件
     * @param response
     * @param id
     */
    public void downloadFilesInGridFs(HttpServletResponse response,String id) {
    	Query query = new Query();
    	query.addCriteria(Criteria.where("_id").is(new ObjectId(id)));
        List<GridFSDBFile> result = gridFsTemplate.find(query);
        GridFSDBFile resultFile = result.get(0);
        if (resultFile!=null) {
			try {
				InputStream in = resultFile.getInputStream();
				response.addHeader("Content-Disposition", "attachment;filename="+new String((resultFile.getFilename()).getBytes("GB2312"),"iso8859-1"));
				response.setContentType("application/octet-stream");	
				try {
					IOUtils.copy(in,response.getOutputStream());    
				} catch (IOException e) {
					e.printStackTrace();
				}finally{
					in.close();
				}
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
    }
}
